from flask import Blueprint, request, jsonify, current_app, g
from flasgger import swag_from
from app import db
from app.models.payment import Payment
from app.models.order import Order
from app.utils.response import success_response, error_response
from app.utils.decorators import login_required
from app.utils.payment_validator import PaymentValidator

payment_bp = Blueprint('user_payments', __name__)

@payment_bp.route('/create', methods=['POST'])
@login_required
@swag_from({
    'tags': ['用户-支付'],
    'summary': '创建支付',
    'description': '''用户为指定订单创建支付，支持微信支付和支付宝，返回支付参数用于调起支付。

**📋 支付流程：**
1. 验证订单状态（必须是未支付状态）
2. 检查订单是否属于当前用户
3. 创建支付记录
4. 调用第三方支付接口获取支付参数
5. 返回支付参数给前端

**💳 支持的支付方式：**
- wechat：微信支付（默认）
- alipay：支付宝支付

**⚠️ 注意事项：**
- 只能为未支付的订单创建支付
- 支付金额必须与订单金额一致
- 支付创建后订单状态不会立即改变，需要等待支付回调
    ''',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'Authorization',
            'in': 'header',
            'required': True,
            'type': 'string',
            'description': 'JWT token，格式：Bearer {token}，从登录接口获取'
        },
        {
            'name': 'body',
            'in': 'body',
            'required': True,
            'schema': {
                'type': 'object',
                'required': ['order_id'],
                'properties': {
                    'order_id': {
                        'type': 'integer', 
                        'description': '订单ID，必须是当前用户的未支付订单',
                        'example': 123
                    },
                    'payment_method': {
                        'type': 'string', 
                        'enum': ['wechat', 'alipay'], 
                        'default': 'wechat', 
                        'description': '''支付方式：
                        • wechat = 微信支付（推荐，支持小程序支付）
                        • alipay = 支付宝支付（需要配置支付宝商户信息）'''
                    }
                },
                'examples': {
                    'wechat_payment': {
                        'summary': '微信支付',
                        'value': {
                            'order_id': 123,
                            'payment_method': 'wechat'
                        }
                    },
                    'alipay_payment': {
                        'summary': '支付宝支付',
                        'value': {
                            'order_id': 123,
                            'payment_method': 'alipay'
                        }
                    }
                }
            }
        }
    ],
    'responses': {
        200: {
            'description': '支付创建成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '支付创建成功'},
                    'data': {
                        'type': 'object',
                        'description': '支付信息',
                        'properties': {
                            'payment_id': {'type': 'integer', 'description': '支付记录ID'},
                            'payment_no': {'type': 'string', 'description': '支付单号'},
                            'amount': {'type': 'number', 'description': '支付金额（元）'},
                            'payment_method': {'type': 'string', 'description': '支付方式'},
                            'payment_params': {
                                'type': 'object', 
                                'description': '''支付参数，用于调起支付：
                                • 微信支付：包含appId、timeStamp、nonceStr、package、signType、paySign等
                                • 支付宝支付：包含orderStr等'''
                            },
                            'expire_time': {'type': 'string', 'description': '支付过期时间'}
                        }
                    }
                }
            }
        },
        400: {
            'description': '请求参数错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 400},
                    'message': {'type': 'string', 'example': '订单不存在或状态不正确'}
                }
            }
        },
        401: {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        403: {
            'description': '无权操作',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 403},
                    'message': {'type': 'string', 'example': '无权操作此订单'}
                }
            }
        },
        500: {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '支付创建失败'}
                }
            }
        }
    }
})
def create_payment():
    """创建支付"""
    try:
        data = request.get_json()
        
        # 验证支付数据
        PaymentValidator.validate_payment_data(data)
        
        # 清理支付数据
        data = PaymentValidator.clean_payment_data(data)
        
        order_id = data['order_id']
        payment_method = data.get('payment_method', 'wechat')
        
        # 验证订单
        order = Order.query.get(order_id)
        if not order:
            return error_response('订单不存在', 404)
        
        # 验证用户权限
        PaymentValidator.validate_user_permission(order, g.current_user_id)
        
        # 验证订单状态
        PaymentValidator.validate_order_status(order)
        
        # 验证支付金额
        PaymentValidator.verify_payment_amount(order_id, order.amount)
        
        # 防止重复支付
        PaymentValidator.prevent_duplicate_payment(order_id)
        
        # 检查支付频率
        PaymentValidator.check_payment_frequency(g.current_user_id)
        
        # 生成支付单号
        import time
        payment_no = f"PAY{int(time.time() * 1000)}{order_id:06d}"
        
        # 创建支付记录
        payment = Payment(
            payment_no=payment_no,
            order_id=order_id,
            user_id=g.current_user_id,
            amount=order.amount,
            payment_method=payment_method,
            status=0  # 未支付状态
        )
        
        db.session.add(payment)
        db.session.commit()
        
        # 记录支付操作日志
        PaymentValidator.log_payment_operation(
            'create_payment',
            payment_id=payment.id,
            order_id=order_id,
            user_id=g.current_user_id,
            details={'amount': float(order.amount), 'payment_method': payment_method}
        )
        
        # 生成支付参数（这里简化处理，实际应调用微信支付或支付宝接口）
        payment_params = {
            'payment_no': payment_no,
            'amount': float(order.amount),
            'description': f'场馆预约支付-{order.order_no}',
            'payment_method': payment_method
        }
        
        if payment_method == 'wechat':
            # 这里应该调用微信支付接口
            payment_params.update({
                'appId': current_app.config.get('WECHAT_APPID', ''),
                'timeStamp': str(int(time.time())),
                'nonceStr': payment_no,
                'package': f'prepay_id=mock_prepay_id_{payment_no}',
                'signType': 'MD5',
                'paySign': 'mock_sign'
            })
        
        return success_response({
            'payment_id': payment.id,
            'payment_no': payment_no,
            'amount': float(order.amount),
            'payment_params': payment_params
        }, '支付创建成功')
        
    except ValueError as e:
        # 验证错误
        current_app.logger.warning(f"支付创建验证失败: {str(e)}")
        return error_response(str(e), 400)
        
    except Exception as e:
        current_app.logger.error(f"创建支付失败: {str(e)}")
        db.session.rollback()
        return error_response('创建支付失败', 500)

@payment_bp.route('/<payment_no>/query', methods=['GET'])
@login_required
@swag_from({
    'tags': ['用户-支付'],
    'summary': '查询支付状态',
    'description': '用户根据支付单号查询支付状态，包含支付金额、状态、时间等详细信息。',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'Authorization',
            'in': 'header',
            'required': True,
            'type': 'string',
            'description': 'JWT token，格式：Bearer {token}，从登录接口获取'
        },
        {
            'name': 'payment_no',
            'in': 'path',
            'type': 'string',
            'required': True,
            'description': '支付单号'
        }
    ],
    'responses': {
        200: {
            'description': '查询成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '查询成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'payment_no': {'type': 'string'},
                            'status': {'type': 'integer'},
                            'status_text': {'type': 'string'},
                            'amount': {'type': 'number'},
                            'paid_at': {'type': 'string'},
                            'order': {'type': 'object'}
                        }
                    }
                }
            }
        }
    }
})
def query_payment(payment_no):
    """查询支付状态"""
    try:
        payment = Payment.query.filter_by(payment_no=payment_no).first()
        if not payment:
            return error_response('支付记录不存在', 404)
        
        # 检查支付是否属于当前用户
        if payment.user_id != g.current_user_id:
            return error_response('无权访问该支付记录', 403)
        
        # 获取关联的订单信息
        order = Order.query.get(payment.order_id)
        
        status_map = {0: '未支付', 1: '支付成功', 2: '支付失败', 3: '已退款'}
        
        payment_data = {
            'payment_no': payment.payment_no,
            'status': payment.status,
            'status_text': status_map.get(payment.status, '未知状态'),
            'amount': float(payment.amount),
            'payment_method': payment.payment_method,
            'created_at': payment.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'paid_at': payment.paid_at.strftime('%Y-%m-%d %H:%M:%S') if payment.paid_at else None
        }
        
        if order:
            payment_data['order'] = order.to_dict()
        
        return success_response(payment_data, '查询成功')
        
    except Exception as e:
        current_app.logger.error(f"查询支付状态失败: {str(e)}")
        return error_response('查询失败', 500)

@payment_bp.route('/my', methods=['GET'])
@login_required
@swag_from({
    'tags': ['用户-支付'],
    'summary': '我的支付记录',
    'description': '用户查看自己的支付记录列表，支持分页和状态筛选，包含支付详情和关联订单信息。',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'Authorization',
            'in': 'header',
            'required': True,
            'type': 'string',
            'description': 'JWT token，格式：Bearer {token}，从登录接口获取'
        },
        {
            'name': 'page',
            'in': 'query',
            'type': 'integer',
            'default': 1,
            'description': '页码'
        },
        {
            'name': 'per_page',
            'in': 'query',
            'type': 'integer',
            'default': 10,
            'description': '每页数量'
        },
        {
            'name': 'status',
            'in': 'query',
            'type': 'integer',
            'enum': [0, 1, 2, 3],
            'description': '支付状态筛选'
        }
    ],
    'responses': {
        200: {
            'description': '获取成功'
        }
    }
})
def get_my_payments():
    """获取我的支付记录"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 50)
        status = request.args.get('status', type=int)
        
        # 构建查询
        query = Payment.query.filter_by(user_id=g.current_user_id)
        
        if status is not None:
            query = query.filter_by(status=status)
        
        # 分页查询
        pagination = query.order_by(Payment.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        payments = []
        status_map = {0: '未支付', 1: '支付成功', 2: '支付失败', 3: '已退款'}
        
        for payment in pagination.items:
            order = Order.query.get(payment.order_id)
            
            payment_data = {
                'id': payment.id,
                'payment_no': payment.payment_no,
                'amount': float(payment.amount),
                'status': payment.status,
                'status_text': status_map.get(payment.status, '未知状态'),
                'payment_method': payment.payment_method,
                'created_at': payment.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                'paid_at': payment.paid_at.strftime('%Y-%m-%d %H:%M:%S') if payment.paid_at else None
            }
            
            if order:
                payment_data['order'] = {
                    'order_no': order.order_no,
                    'reservation_date': order.reservation_date.strftime('%Y-%m-%d'),
                    'venue_id': order.venue_id
                }
            
            payments.append(payment_data)
        
        return success_response({
            'payments': payments,
            'total': pagination.total,
            'page': page,
            'pages': pagination.pages,
            'per_page': per_page
        }, '获取成功')
        
    except Exception as e:
        current_app.logger.error(f"获取我的支付记录失败: {str(e)}")
        return error_response('获取失败', 500) 